from stream import Stream
from source import Source
from utils.label import Label
import defs.exception as exception
import os, os.path, stat, struct

class Folder(Stream, Source):
    def __init__(self, path):
        #assert isinstance(label, Label)
        abspath = os.path.abspath(path)
        if abspath[-1:] == "\\":
            abspath = abspath[:-1]
        self.label = Label(abspath)
        
    
    def open(self):
        pass
        
    def seek(self, offset, whence = os.SEEK_SET):
        pass
        
    def getSize(self):
        pass
        #TODO
        
    def addOutBranch(self, outstream):
        pass 
  
    def close(self):
        pass
    
    def tell(self):
        pass
    
    def read(self, size = -1):
        #print "\n", self.label.text
        return "\n".join([x for x in self.genitem(self.label.text)])
        
    def write(self, data):
        cmd = data[:4]
        assert cmd == cmd.upper()
        param = data[4:]
        {
        "CHD " : self.chdir,
        "CRD " : self.mkdir, 
        "RMD " : self.rmdir
        }[cmd](param)
    
    def chdir(self, dirpath):
        #print "!!!", dirpath, "!!!\n"
        if not os.path.isabs(dirpath):
            if dirpath[0] != "/" and dirpath[1] == ":":
                fullpath = dirpath
            else:
                fullpath = self.label.text + os.sep + dirpath
        else:
            fullpath = dirpath
        if not os.path.isdir(fullpath):
            return
        self.label = Label(fullpath)
        
    def mkdir(self, dirpath):
        #print "!!!", dirpath, "\n"
        if not os.path.isabs(dirpath):
            fullpath = self.label.text + os.sep + dirpath
        else:
            fullpath = dirpath
        #print "!!!", fullpath, "\n"
        if os.path.exists(fullpath):
            return
        os.mkdir(fullpath)
        
    def rmdir(self, dirpath):

        if not os.path.isabs(dirpath):
            fullpath = self.label.text + os.sep + dirpath
        else:
            fullpath = dirpath
        if os.path.isdir(fullpath):
            os.rmdir(fullpath)
    
    def genitem(self, path):
        #print "path is", path
        for item in os.listdir(path):
            yield self.formatitem(path, item)
            
    def formatitem(self, path, item):
        fullpath = path + os.sep + item
        assert os.path.isabs(fullpath)
        
        stats = os.stat(fullpath)
        statinfo = StatInfo()
        return statinfo.encode(stats, item)
        
class StatInfo:
    def __init__(self):
        self.dict = {}
        
    def __setitem__(self, key, value):
        self.dict[key] = value
        
    def __getitem__(self, key):
        return self.dict.get(key)
     
    def encode(self, stats, name):
        self["isdir"] = stat.S_ISDIR(stats.st_mode)
        self["size"] = stats.st_size
        self["name"] = name
        #return "".join([self["isdir"] and "d" or " ", struct.pack("Q", self["size"]), self["name"]])
        return "".join([self["isdir"] and "d" or " ", "%12x" % self["size"], self["name"]])
    
    def decode(self, statline):
        self["isdir"] = {"d":True, " ":False}[statline[0]]
        assert len(statline[1:13]) == 12
        #self["size"] = struct.unpack("Q", statline[1:9])
        self["size"] = int(statline[1:13], 16)
        self["name"] = statline[13:]
    
